
# 所用到的模块
# requirements.txt
alembic==1.3.1
SQLAlchemy==1.3.8
Flask==1.1.1
Flask_Script==2.0.6 # 用于生成命令
Flask_SQLAlchemy==2.4.0
redis==3.3.4
Flask_Session==0.3.1
Flask_Migrate==2.5.2 # 对数据库表进行增删改
# manage.py
from flask_script import Manager
from flask_migrate import Migrate, MigrateCommand
from flask_directory_structure import create_app, db
app = create_app()
manage = Manager(app)
Migrate(app, db)
manage.add_command('db', MigrateCommand) # 添加数据库迁移命令
if __name__ == '__main__':
manage.run() # 必须使用 manage.run() 进行启动,否则 migrate 的数据库迁移的命令无法使用
# 通过 Manage 和 Migrate 模块所生成的命令
python manage.py runserver # 启动项目
python manage.py db init # 初始化 migrations 文件夹用于记录表的修改情况,只执行一次
python manage.py db migrate # 类似于 Django 中的 makemigrations
python manage.py db upgrade # 类似于 Django 中的 migrate
# settings.py
from redis import Redis
class BaseConfig(object):
# session 配置
SESSION_TYPE = 'redis' # session所保存的位置
SESSION_REDIS = Redis() # 配置redis连接对象(即: 设置该连接那个redis),如果不设置默认使用本地ip+6379端口的redis进行连接
# SQLAlchemy 配置
SQLALCHEMY_DATABASE_URI = 'mysql+pymysql://root:@127.0.0.1:3306/db1?charset=utf8' # 连接那个数据库
SQLALCHEMY_MAX_OVERFLOW = 10 # 允许溢出多少个连接(即:连接池的连接已满后,还可以创建多少条连接)
SQLALCHEMY_POOL_SIZE = 5 # 连接池中的连接数
SQLALCHEMY_POOL_TIMEOUT = 10 # 连接池中没有线程后最多等待的时间(单位:秒),如果超过指定时间还没有连接就报错
SQLALCHEMY_POOL_RECYCLE = -1 # 多久之后对线程池中的线程进行一次连接的回收(重置)(单位:秒)-> -1表示不重置
SQLALCHEMY_TRACK_MODIFICATIONS = False # 关闭信号的追踪,如果不关闭会有一个无关紧要的异常
class ProConfig(BaseConfig):
pass
# flask_directory_structure/__init__.py
from flask import Flask
from flask_session import Session
from flask_sqlalchemy import SQLAlchemy # 需要依赖app中的配置文件
# 实例化 SQLAlchemy -> 一定要设置为全局变量,且在视图文件和models文件上面
db = SQLAlchemy() # 创建一个 SQLAlchemy 所用到的所有东西的一个对象,唯独少了数据库连接
from .views.account import ac
from .views.home import hm
from .models import * # 如果不导入 flask_sqlalchemy 就不会创建表,因为 models.py 没有被执行
def create_app():
app = Flask(__name__)
# 设置 app 的配置项
app.config.from_object('settings.ProConfig')
# 注册蓝图
app.register_blueprint(ac)
app.register_blueprint(hm)
# 实例化 Flask-Session
Session(app)
# 从app配置文件中获取相关的 SQLAlchemy 配置
db.init_app(app) # 通过读取app的配置文件获取到数据库的连接
return app
# flask_directory_structure/models.py
from sqlalchemy import Column, Integer, VARCHAR
from flask_directory_structure import db
# Users 表的类
class Users(db.Model): # 创建表的类一定要继承 db.Model
__tablename__ = 'users' # 表名
id = Column(Integer, primary_key=True, autoincrement=True) # 整型 设置主键 设置自增列
name = Column(VARCHAR(32), nullable=False, index=True) # varchar类型(长度:32) 不允许为空 将name字段设置为索引
age = Column(Integer) # 整形
address = Column(VARCHAR(32)) # varchar类型(长度:32)
# flask_directory_structure/views/account.py
from flask import Blueprint, render_template
from flask_directory_structure import db
from flask_directory_structure import models
ac = Blueprint('ac', __name__)
@ac.route('/login')
def login():
# db.session 为每个线程去数据库连接池中获取一个连接,实际上是调用了 scoped_session
# 添加数据
# db.session.add(models.Users(name='Kevin', age=18, address='横沥'))
# db.session.commit()
# db.session.remove()
# 查询数据
# result = db.session.query(models.Users.name, models.Users.address).all()
# print(result)
# db.session.remove()
return render_template('login.html')
# flask_directory_structure/templates/login.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>login</title>
<link rel="stylesheet" href="/static/reset.css">
</head>
<body>
登陆
</body>
</html>
# flask_directory_structure/views/home.py
from flask import Blueprint, render_template
hm = Blueprint('hm', __name__)
@hm.route('/home')
def home():
return render_template('home.html')
# flask_directory_structure/templates/home.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>home</title>
<link rel="stylesheet" href="/static/reset.css">
</head>
<body>
首页
</body>
</html>
# flask_directory_structure/static/reset.css
html, body, div, span, applet, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
a, abbr, acronym, address, big, cite, code,
del, dfn, em, img, ins, kbd, q, s, samp,
small, strike, strong, sub, sup, tt, var,
b, u, i, center,
dl, dt, dd, ol, ul, li,
fieldset, form, label, legend,
table, caption, tbody, tfoot, thead, tr, th, td,
article, aside, canvas, details, embed,
figure, figcaption, footer, header, hgroup,
menu, nav, output, ruby, section, summary,
time, mark, audio, video {
margin: 0;
padding: 0;
border: 0;
font-size: 100%;
font: inherit;
vertical-align: baseline;
}
/* HTML5 display-role reset for older browsers */
article, aside, details, figcaption, figure,
footer, header, hgroup, menu, nav, section {
display: block;
}
body {
line-height: 1;
}
ol, ul {
list-style: none;
}
blockquote, q {
quotes: none;
}
blockquote:before, blockquote:after,
q:before, q:after {
content: '';
content: none;
}
table {
border-collapse: collapse;
border-spacing: 0;
}